home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume7 / 2.11news / part12 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  60.8 KB

  1. Subject:  v07i052:  2.11 News Source, Part02/09
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!rick (Rick Adams)
  6. Mod.sources: Volume 7, Issue 52
  7. Archive-name: 2.11news/Part12
  8.  
  9. # To extract, sh this file
  10. #
  11. #    news 2.11 source part 2 of 9
  12. #
  13. if test ! -d src
  14. then
  15.     mkdir src
  16. fi
  17. echo x - src/compress.c 1>&2
  18. sed 's/.//' >src/compress.c <<'*-*-END-of-src/compress.c-*-*'
  19. -#ifdef SCCSID
  20. -static char    *SccsId = "@(#)compress.c    1.12    10/29/86";
  21. -#endif SCCSID
  22. -static char rcs_ident[] = "Based on compress.c,v 4.0 85/07/30 12:50:00 joe Release";
  23. -
  24. -/* 
  25. - * Compress - data compression program 
  26. - */
  27. -#define    min(a,b)    ((a>b) ? b : a)
  28. -
  29. -/*
  30. - * machine variants which require cc -Dmachine:  pdp11, z8000, pcxt
  31. - */
  32. -
  33. -/*
  34. - * Set USERMEM to the maximum amount of physical user memory available
  35. - * in bytes.  USERMEM is used to determine the maximum BITS that can be used
  36. - * for compression.
  37. - *
  38. - * SACREDMEM is the amount of physical memory saved for others; compress
  39. - * will hog the rest.
  40. - */
  41. -#ifndef SACREDMEM
  42. -#define SACREDMEM    0
  43. -#endif
  44. -
  45. -#ifndef USERMEM
  46. -# define USERMEM     450000    /* default user memory */
  47. -#endif
  48. -
  49. -#ifdef interdata        /* (Perkin-Elmer) */
  50. -#define SIGNED_COMPARE_SLOW    /* signed compare is slower than unsigned */
  51. -#endif
  52. -
  53. -#ifdef pdp11
  54. -# define BITS     12    /* max bits/code for 16-bit machine */
  55. -# define NO_UCHAR    /* also if "unsigned char" functions as signed char */
  56. -# undef USERMEM 
  57. -#endif /* pdp11 */    /* don't forget to compile with -i */
  58. -
  59. -#ifdef z8000
  60. -# define BITS     12
  61. -# undef vax        /* weird preprocessor */
  62. -# undef USERMEM 
  63. -#endif /* z8000 */
  64. -
  65. -#ifdef pcxt
  66. -# define BITS   12
  67. -# undef USERMEM
  68. -#endif /* pcxt */
  69. -
  70. -#ifdef USERMEM
  71. -# if USERMEM >= (433484+SACREDMEM)
  72. -#  define PBITS    16
  73. -# else
  74. -#  if USERMEM >= (229600+SACREDMEM)
  75. -#   define PBITS    15
  76. -#  else
  77. -#   if USERMEM >= (127536+SACREDMEM)
  78. -#    define PBITS    14
  79. -#   else
  80. -#    if USERMEM >= (73464+SACREDMEM)
  81. -#     define PBITS    13
  82. -#    else
  83. -#     define PBITS    12
  84. -#    endif
  85. -#   endif
  86. -#  endif
  87. -# endif
  88. -# undef USERMEM
  89. -#endif /* USERMEM */
  90. -
  91. -#ifdef PBITS        /* Preferred BITS for this memory size */
  92. -# ifndef BITS
  93. -#  define BITS PBITS
  94. -# endif BITS
  95. -#endif /* PBITS */
  96. -
  97. -#if BITS == 16
  98. -# define HSIZE    69001        /* 95% occupancy */
  99. -#endif
  100. -#if BITS == 15
  101. -# define HSIZE    35023        /* 94% occupancy */
  102. -#endif
  103. -#if BITS == 14
  104. -# define HSIZE    18013        /* 91% occupancy */
  105. -#endif
  106. -#if BITS == 13
  107. -# define HSIZE    9001        /* 91% occupancy */
  108. -#endif
  109. -#if BITS <= 12
  110. -# define HSIZE    5003        /* 80% occupancy */
  111. -#endif
  112. -
  113. -#ifdef M_XENIX            /* Stupid compiler can't handle arrays with */
  114. -# if BITS == 16            /* more than 65535 bytes - so we fake it */
  115. -#  define XENIX_16
  116. -# else
  117. -#  if BITS > 13            /* Code only handles BITS = 12, 13, or 16 */
  118. -#   define BITS    13
  119. -#  endif
  120. -# endif
  121. -#endif
  122. -
  123. -/*
  124. - * a code_int must be able to hold 2**BITS values of type int, and also -1
  125. - */
  126. -#if BITS > 15
  127. -typedef long int    code_int;
  128. -#else
  129. -typedef int        code_int;
  130. -#endif
  131. -
  132. -#ifdef SIGNED_COMPARE_SLOW
  133. -typedef unsigned long int count_int;
  134. -typedef unsigned short int count_short;
  135. -#else
  136. -typedef long int      count_int;
  137. -#endif
  138. -
  139. -#ifdef NO_UCHAR
  140. - typedef char    char_type;
  141. -#else
  142. - typedef    unsigned char    char_type;
  143. -#endif /* UCHAR */
  144. -char_type magic_header[] = { "\037\235" };    /* 1F 9D */
  145. -
  146. -/* Defines for third byte of header */
  147. -#define BIT_MASK    0x1f
  148. -#define BLOCK_MASK    0x80
  149. -/* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
  150. -   a fourth header byte (for expansion).
  151. -*/
  152. -#define INIT_BITS 9            /* initial number of bits/code */
  153. -
  154. -/*
  155. - * compress.c - File compression ala IEEE Computer, June 1984.
  156. - *
  157. - * Authors:    Spencer W. Thomas    (decvax!harpo!utah-cs!utah-gr!thomas)
  158. - *        Jim McKie        (decvax!mcvax!jim)
  159. - *        Steve Davies        (decvax!vax135!petsd!peora!srd)
  160. - *        Ken Turkowski        (decvax!decwrl!turtlevax!ken)
  161. - *        James A. Woods        (decvax!ihnp4!ames!jaw)
  162. - *        Joe Orost        (decvax!vax135!petsd!joe)
  163. - *
  164. - */
  165. -
  166. -#include <stdio.h>
  167. -#include <ctype.h>
  168. -#include <signal.h>
  169. -#include <sys/types.h>
  170. -#include <sys/stat.h>
  171. -
  172. -#define ARGVAL() (*++(*argv) || (--argc && *++argv))
  173. -
  174. -int n_bits;                /* number of bits/code */
  175. -int maxbits = BITS;            /* user settable max # bits/code */
  176. -code_int maxcode;            /* maximum code, given n_bits */
  177. -code_int maxmaxcode = 1L << BITS;    /* should NEVER generate this code */
  178. -#ifdef COMPATIBLE        /* But wrong! */
  179. -# define MAXCODE(n_bits)    (1 << (n_bits) - 1)
  180. -#else
  181. -# define MAXCODE(n_bits)    ((1 << (n_bits)) - 1)
  182. -#endif /* COMPATIBLE */
  183. -
  184. -#ifdef XENIX_16
  185. -count_int htab0[8192];
  186. -count_int htab1[8192];
  187. -count_int htab2[8192];
  188. -count_int htab3[8192];
  189. -count_int htab4[8192];
  190. -count_int htab5[8192];
  191. -count_int htab6[8192];
  192. -count_int htab7[8192];
  193. -count_int htab8[HSIZE-65536];
  194. -count_int * htab[9] = {
  195. -    htab0, htab1, htab2, htab3, htab4, htab5, htab6, htab7, htab8 };
  196. -
  197. -#define htabof(i)    (htab[(i) >> 13][(i) & 0x1fff])
  198. -unsigned short code0tab[16384];
  199. -unsigned short code1tab[16384];
  200. -unsigned short code2tab[16384];
  201. -unsigned short code3tab[16384];
  202. -unsigned short code4tab[16384];
  203. -unsigned short * codetab[5] = {
  204. -    code0tab, code1tab, code2tab, code3tab, code4tab };
  205. -
  206. -#define codetabof(i)    (codetab[(i) >> 14][(i) & 0x3fff])
  207. -
  208. -#else    /* Normal machine */
  209. -# ifdef sel
  210. -/* support gould base register problems */
  211. -/*NOBASE*/
  212. -count_int htab [HSIZE];
  213. -unsigned short codetab [HSIZE];
  214. -/*NOBASE*/
  215. -# else /* !gould */
  216. -count_int htab [HSIZE];
  217. -unsigned short codetab [HSIZE];
  218. -# endif /* !gould */
  219. -#define htabof(i)    htab[i]
  220. -#define codetabof(i)    codetab[i]
  221. -#endif    /* !XENIX_16 */
  222. -code_int hsize = HSIZE;            /* for dynamic table sizing */
  223. -count_int fsize;
  224. -
  225. -/*
  226. - * To save much memory, we overlay the table used by compress() with those
  227. - * used by decompress().  The tab_prefix table is the same size and type
  228. - * as the codetab.  The tab_suffix table needs 2**BITS characters.  We
  229. - * get this from the beginning of htab.  The output stack uses the rest
  230. - * of htab, and contains characters.  There is plenty of room for any
  231. - * possible stack (stack used to be 8000 characters).
  232. - */
  233. -
  234. -#define tab_prefixof(i)    codetabof(i)
  235. -#ifdef XENIX_16
  236. -# define tab_suffixof(i)    ((char_type *)htab[(i)>>15])[(i) & 0x7fff]
  237. -# define de_stack        ((char_type *)(htab2))
  238. -#else    /* Normal machine */
  239. -# define tab_suffixof(i)    ((char_type *)(htab))[i]
  240. -# define de_stack        ((char_type *)&tab_suffixof(1<<BITS))
  241. -#endif    /* XENIX_16 */
  242. -
  243. -code_int free_ent = 0;            /* first unused entry */
  244. -int exit_stat = 0;
  245. -
  246. -code_int getcode();
  247. -
  248. -Usage() {
  249. -#ifdef DEBUG
  250. -fprintf(stderr,"Usage: compress [-dDVfc] [-b maxbits] [file ...]\n");
  251. -}
  252. -int debug = 0;
  253. -#else
  254. -fprintf(stderr,"Usage: compress [-dfvcV] [-b maxbits] [file ...]\n");
  255. -}
  256. -#endif /* DEBUG */
  257. -int nomagic = 0;    /* Use a 3-byte magic number header, unless old file */
  258. -int zcat_flg = 0;    /* Write output on stdout, suppress messages */
  259. -int quiet = 1;        /* don't tell me about compression */
  260. -
  261. -/*
  262. - * block compression parameters -- after all codes are used up,
  263. - * and compression rate changes, start over.
  264. - */
  265. -int block_compress = BLOCK_MASK;
  266. -int clear_flg = 0;
  267. -long int ratio = 0;
  268. -#define CHECK_GAP 10000    /* ratio check interval */
  269. -count_int checkpoint = CHECK_GAP;
  270. -/*
  271. - * the next two codes should not be changed lightly, as they must not
  272. - * lie within the contiguous general code space.
  273. - */ 
  274. -#define FIRST    257    /* first free entry */
  275. -#define    CLEAR    256    /* table clear output code */
  276. -
  277. -int force = 0;
  278. -char ofname [100];
  279. -#ifdef DEBUG
  280. -int verbose = 0;
  281. -#endif /* DEBUG */
  282. -int (*bgnd_flag)();
  283. -
  284. -int do_decomp = 0;
  285. -
  286. -/*****************************************************************
  287. - * TAG( main )
  288. - *
  289. - * Algorithm from "A Technique for High Performance Data Compression",
  290. - * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
  291. - *
  292. - * Usage: compress [-dfvc] [-b bits] [file ...]
  293. - * Inputs:
  294. - *    -d:        If given, decompression is done instead.
  295. - *
  296. - *      -c:         Write output on stdout, don't remove original.
  297. - *
  298. - *      -b:         Parameter limits the max number of bits/code.
  299. - *
  300. - *    -f:        Forces output file to be generated, even if one already
  301. - *            exists, and even if no space is saved by compressing.
  302. - *            If -f is not used, the user will be prompted if stdin is
  303. - *            a tty, otherwise, the output file will not be overwritten.
  304. - *
  305. - *      -v:        Write compression statistics
  306. - *
  307. - *     file ...:   Files to be compressed.  If none specified, stdin
  308. - *            is used.
  309. - * Outputs:
  310. - *    file.Z:        Compressed form of file with same mode, owner, and utimes
  311. - *     or stdout   (if stdin used as input)
  312. - *
  313. - * Assumptions:
  314. - *    When filenames are given, replaces with the compressed version
  315. - *    (.Z suffix) only if the file decreases in size.
  316. - * Algorithm:
  317. - *     Modified Lempel-Ziv method (LZW).  Basically finds common
  318. - * substrings and replaces them with a variable size code.  This is
  319. - * deterministic, and can be done on the fly.  Thus, the decompression
  320. - * procedure needs no input table, but tracks the way the table was built.
  321. - */
  322. -
  323. -main( argc, argv )
  324. -register int argc; char **argv;
  325. -{
  326. -    int overwrite = 0;    /* Do not overwrite unless given -f flag */
  327. -    char tempname[100];
  328. -    char **filelist, **fileptr;
  329. -    char *cp, *rindex(), *malloc();
  330. -    struct stat statbuf;
  331. -    extern onintr(), oops();
  332. -
  333. -
  334. -    if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
  335. -    signal ( SIGINT, onintr );
  336. -    signal ( SIGSEGV, oops );
  337. -    }
  338. -
  339. -#ifdef COMPATIBLE
  340. -    nomagic = 1;    /* Original didn't have a magic number */
  341. -#endif /* COMPATIBLE */
  342. -
  343. -    filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
  344. -    *filelist = NULL;
  345. -
  346. -    if((cp = rindex(argv[0], '/')) != 0) {
  347. -    cp++;
  348. -    } else {
  349. -    cp = argv[0];
  350. -    }
  351. -    if(strcmp(cp, "uncompress") == 0) {
  352. -    do_decomp = 1;
  353. -    } else if(strcmp(cp, "zcat") == 0) {
  354. -    do_decomp = 1;
  355. -    zcat_flg = 1;
  356. -    }
  357. -
  358. -#ifdef BSD4_2
  359. -    /* 4.2BSD dependent - take it out if not */
  360. -    setlinebuf( stderr );
  361. -#endif /* BSD4_2 */
  362. -
  363. -    /* Argument Processing
  364. -     * All flags are optional.
  365. -     * -D => debug
  366. -     * -V => print Version; debug verbose
  367. -     * -d => do_decomp
  368. -     * -v => unquiet
  369. -     * -f => force overwrite of output file
  370. -     * -n => no header: useful to uncompress old files
  371. -     * -b maxbits => maxbits.  If -b is specified, then maxbits MUST be
  372. -     *        given also.
  373. -     * -c => cat all output to stdout
  374. -     * -C => generate output compatible with compress 2.0.
  375. -     * if a string is left, must be an input filename.
  376. -     */
  377. -    for (argc--, argv++; argc > 0; argc--, argv++) {
  378. -    if (**argv == '-') {    /* A flag argument */
  379. -        while (*++(*argv)) {    /* Process all flags in this arg */
  380. -        switch (**argv) {
  381. -#ifdef DEBUG
  382. -            case 'D':
  383. -            debug = 1;
  384. -            break;
  385. -            case 'V':
  386. -            verbose = 1;
  387. -            version();
  388. -            break;
  389. -#else
  390. -            case 'V':
  391. -            version();
  392. -            break;
  393. -#endif /* DEBUG */
  394. -            case 'v':
  395. -            quiet = 0;
  396. -            break;
  397. -            case 'd':
  398. -            do_decomp = 1;
  399. -            break;
  400. -            case 'f':
  401. -            case 'F':
  402. -            overwrite = 1;
  403. -            force = 1;
  404. -            break;
  405. -            case 'n':
  406. -            nomagic = 1;
  407. -            break;
  408. -            case 'C':
  409. -            block_compress = 0;
  410. -            break;
  411. -            case 'b':
  412. -            if (!ARGVAL()) {
  413. -                fprintf(stderr, "Missing maxbits\n");
  414. -                Usage();
  415. -                exit(1);
  416. -            }
  417. -            maxbits = atoi(*argv);
  418. -            goto nextarg;
  419. -            case 'c':
  420. -            zcat_flg = 1;
  421. -            break;
  422. -            case 'q':
  423. -            quiet = 1;
  424. -            break;
  425. -            default:
  426. -            fprintf(stderr, "Unknown flag: '%c'; ", **argv);
  427. -            Usage();
  428. -            exit(1);
  429. -        }
  430. -        }
  431. -    }
  432. -    else {        /* Input file name */
  433. -        *fileptr++ = *argv;    /* Build input file list */
  434. -        *fileptr = NULL;
  435. -        /* process nextarg; */
  436. -    }
  437. -    nextarg: continue;
  438. -    }
  439. -
  440. -    if(maxbits < INIT_BITS) maxbits = INIT_BITS;
  441. -    if (maxbits > BITS) maxbits = BITS;
  442. -    maxmaxcode = 1L << maxbits;
  443. -
  444. -    if (*filelist != NULL) {
  445. -    for (fileptr = filelist; *fileptr; fileptr++) {
  446. -        exit_stat = 0;
  447. -        if (do_decomp != 0) {            /* DECOMPRESSION */
  448. -        /* Check for .Z suffix */
  449. -        if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) {
  450. -            /* No .Z: tack one on */
  451. -            strcpy(tempname, *fileptr);
  452. -            strcat(tempname, ".Z");
  453. -            *fileptr = tempname;
  454. -        }
  455. -        /* Open input file */
  456. -        if ((freopen(*fileptr, "r", stdin)) == NULL) {
  457. -            perror(*fileptr); continue;
  458. -        }
  459. -        /* Check the magic number */
  460. -        if (nomagic == 0) {
  461. -            if ((getchar() != (magic_header[0] & 0xFF))
  462. -             || (getchar() != (magic_header[1] & 0xFF))) {
  463. -            fprintf(stderr, "%s: not in compressed format\n",
  464. -                *fileptr);
  465. -            continue;
  466. -            }
  467. -            maxbits = getchar();    /* set -b from file */
  468. -            block_compress = maxbits & BLOCK_MASK;
  469. -            maxbits &= BIT_MASK;
  470. -            maxmaxcode = 1L << maxbits;
  471. -            if(maxbits > BITS) {
  472. -            fprintf(stderr,
  473. -            "%s: compressed with %d bits, can only handle %d bits\n",
  474. -            *fileptr, maxbits, BITS);
  475. -            continue;
  476. -            }
  477. -        }
  478. -        /* Generate output filename */
  479. -        strcpy(ofname, *fileptr);
  480. -        ofname[strlen(*fileptr) - 2] = '\0';  /* Strip off .Z */
  481. -        } else {                    /* COMPRESSION */
  482. -        if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) {
  483. -                fprintf(stderr, "%s: already has .Z suffix -- no change\n",
  484. -                *fileptr);
  485. -            continue;
  486. -        }
  487. -        /* Open input file */
  488. -        if ((freopen(*fileptr, "r", stdin)) == NULL) {
  489. -            perror(*fileptr); continue;
  490. -        }
  491. -        stat ( *fileptr, &statbuf );
  492. -        fsize = (long) statbuf.st_size;
  493. -        /*
  494. -         * tune hash table size for small files -- ad hoc,
  495. -         * but the sizes match earlier #defines, which
  496. -         * serve as upper bounds on the number of output codes. 
  497. -         */
  498. -        hsize = HSIZE;
  499. -        if ( fsize < (1 << 12) )
  500. -            hsize = min ( 5003, HSIZE );
  501. -        else if ( fsize < (1 << 13) )
  502. -            hsize = min ( 9001, HSIZE );
  503. -        else if ( fsize < (1 << 14) )
  504. -            hsize = min ( 18013, HSIZE );
  505. -        else if ( fsize < (1 << 15) )
  506. -            hsize = min ( 35023, HSIZE );
  507. -        else if ( fsize < 47000 )
  508. -            hsize = min ( 50021, HSIZE );
  509. -
  510. -        /* Generate output filename */
  511. -        strcpy(ofname, *fileptr);
  512. -#ifndef BSD4_2        /* Short filenames */
  513. -        if ((cp=rindex(ofname,'/')) != NULL)    cp++;
  514. -        else                    cp = ofname;
  515. -        if (strlen(cp) > 12) {
  516. -            fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
  517. -            continue;
  518. -        }
  519. -#endif  /* BSD4_2        Long filenames allowed */
  520. -        strcat(ofname, ".Z");
  521. -        }
  522. -        /* Check for overwrite of existing file */
  523. -        if (overwrite == 0 && zcat_flg == 0) {
  524. -        if (stat(ofname, &statbuf) == 0) {
  525. -            char response[2];
  526. -            response[0] = 'n';
  527. -            fprintf(stderr, "%s already exists;", ofname);
  528. -            if (foreground()) {
  529. -            fprintf(stderr, " do you wish to overwrite %s (y or n)? ",
  530. -            ofname);
  531. -            fflush(stderr);
  532. -            read(2, response, 2);
  533. -            while (response[1] != '\n') {
  534. -                if (read(2, response+1, 1) < 0) {    /* Ack! */
  535. -                perror("stderr"); break;
  536. -                }
  537. -            }
  538. -            }
  539. -            if (response[0] != 'y') {
  540. -            fprintf(stderr, "\tnot overwritten\n");
  541. -            continue;
  542. -            }
  543. -        }
  544. -        }
  545. -        if(zcat_flg == 0) {        /* Open output file */
  546. -        if (freopen(ofname, "w", stdout) == NULL) {
  547. -            perror(ofname);
  548. -            continue;
  549. -        }
  550. -        if(!quiet)
  551. -            fprintf(stderr, "%s: ", *fileptr);
  552. -        }
  553. -
  554. -        /* Actually do the compression/decompression */
  555. -        if (do_decomp == 0)    compress();
  556. -#ifndef DEBUG
  557. -        else            decompress();
  558. -#else
  559. -        else if (debug == 0)    decompress();
  560. -        else            printcodes();
  561. -        if (verbose)        dump_tab();
  562. -#endif /* DEBUG */
  563. -        if(zcat_flg == 0) {
  564. -        copystat(*fileptr, ofname);    /* Copy stats */
  565. -        if((exit_stat == 1) || (!quiet))
  566. -            putc('\n', stderr);
  567. -        }
  568. -    }
  569. -    } else {        /* Standard input */
  570. -    if (do_decomp == 0) {
  571. -        compress();
  572. -#ifdef DEBUG
  573. -        if(verbose)        dump_tab();
  574. -#endif /* DEBUG */
  575. -        if(!quiet)
  576. -            putc('\n', stderr);
  577. -    } else {
  578. -        /* Check the magic number */
  579. -        if (nomagic == 0) {
  580. -        if ((getchar()!=(magic_header[0] & 0xFF))
  581. -         || (getchar()!=(magic_header[1] & 0xFF))) {
  582. -            fprintf(stderr, "stdin: not in compressed format\n");
  583. -            exit(1);
  584. -        }
  585. -        maxbits = getchar();    /* set -b from file */
  586. -        block_compress = maxbits & BLOCK_MASK;
  587. -        maxbits &= BIT_MASK;
  588. -        maxmaxcode = 1L << maxbits;
  589. -        fsize = 100000;        /* assume stdin large for USERMEM */
  590. -        if(maxbits > BITS) {
  591. -            fprintf(stderr,
  592. -            "stdin: compressed with %d bits, can only handle %d bits\n",
  593. -            maxbits, BITS);
  594. -            exit(1);
  595. -        }
  596. -        }
  597. -#ifndef DEBUG
  598. -        decompress();
  599. -#else
  600. -        if (debug == 0)    decompress();
  601. -        else        printcodes();
  602. -        if (verbose)    dump_tab();
  603. -#endif /* DEBUG */
  604. -    }
  605. -    }
  606. -    exit(exit_stat);
  607. -}
  608. -
  609. -static int offset;
  610. -long int in_count = 1;            /* length of input */
  611. -long int bytes_out;            /* length of compressed output */
  612. -long int out_count = 0;            /* # of codes output (for debugging) */
  613. -
  614. -/*
  615. - * compress stdin to stdout
  616. - *
  617. - * Algorithm:  use open addressing double hashing (no chaining) on the 
  618. - * prefix code / next character combination.  We do a variant of Knuth's
  619. - * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
  620. - * secondary probe.  Here, the modular division first probe is gives way
  621. - * to a faster exclusive-or manipulation.  Also do block compression with
  622. - * an adaptive reset, whereby the code table is cleared when the compression
  623. - * ratio decreases, but after the table fills.  The variable-length output
  624. - * codes are re-sized at this point, and a special CLEAR code is generated
  625. - * for the decompressor.  Late addition:  construct the table according to
  626. - * file size for noticeable speed improvement on small files.  Please direct
  627. - * questions about this implementation to ames!jaw.
  628. - */
  629. -
  630. -compress() {
  631. -    register long fcode;
  632. -    register code_int i = 0;
  633. -    register int c;
  634. -    register code_int ent;
  635. -#ifdef XENIX_16
  636. -    register code_int disp;
  637. -#else    /* Normal machine */
  638. -    register int disp;
  639. -#endif
  640. -    register code_int hsize_reg;
  641. -    register int hshift;
  642. -
  643. -#ifndef COMPATIBLE
  644. -    if (nomagic == 0) {
  645. -    putchar(magic_header[0]); putchar(magic_header[1]);
  646. -    putchar((char)(maxbits | block_compress));
  647. -    if(ferror(stdout))
  648. -        writeerr();
  649. -    }
  650. -#endif /* COMPATIBLE */
  651. -
  652. -    offset = 0;
  653. -    bytes_out = 3;        /* includes 3-byte header mojo */
  654. -    out_count = 0;
  655. -    clear_flg = 0;
  656. -    ratio = 0;
  657. -    in_count = 1;
  658. -    checkpoint = CHECK_GAP;
  659. -    maxcode = MAXCODE(n_bits = INIT_BITS);
  660. -    free_ent = ((block_compress) ? FIRST : 256 );
  661. -
  662. -    ent = getchar ();
  663. -
  664. -    hshift = 0;
  665. -    for ( fcode = (long) hsize;  fcode < 65536L; fcode *= 2L )
  666. -        hshift++;
  667. -    hshift = 8 - hshift;        /* set hash code range bound */
  668. -
  669. -    hsize_reg = hsize;
  670. -    cl_hash( (count_int) hsize_reg);        /* clear hash table */
  671. -
  672. -#ifdef SIGNED_COMPARE_SLOW
  673. -    while ( (c = getchar()) != (unsigned) EOF ) {
  674. -#else
  675. -    while ( (c = getchar()) != EOF ) {
  676. -#endif
  677. -    in_count++;
  678. -    fcode = (long) (((long) c << maxbits) + ent);
  679. -     i = (((long)c << hshift) ^ ent);    /* xor hashing */
  680. -
  681. -    if ( htabof (i) == fcode ) {
  682. -        ent = codetabof (i);
  683. -        continue;
  684. -    } else if ( (long)htabof (i) < 0 )    /* empty slot */
  685. -        goto nomatch;
  686. -     disp = hsize_reg - i;        /* secondary hash (after G. Knott) */
  687. -    if ( i == 0 )
  688. -        disp = 1;
  689. -probe:
  690. -    if ( (i -= disp) < 0 )
  691. -        i += hsize_reg;
  692. -
  693. -    if ( htabof (i) == fcode ) {
  694. -        ent = codetabof (i);
  695. -        continue;
  696. -    }
  697. -    if ( (long)htabof (i) > 0 ) 
  698. -        goto probe;
  699. -nomatch:
  700. -    output ( (code_int) ent );
  701. -    out_count++;
  702. -     ent = c;
  703. -#ifdef SIGNED_COMPARE_SLOW
  704. -    if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
  705. -#else
  706. -    if ( free_ent < maxmaxcode ) {
  707. -#endif
  708. -         codetabof (i) = free_ent++;    /* code -> hashtable */
  709. -        htabof (i) = fcode;
  710. -    }
  711. -    else if ( (count_int)in_count >= checkpoint && block_compress )
  712. -        cl_block ();
  713. -    }
  714. -    /*
  715. -     * Put out the final code.
  716. -     */
  717. -    output( (code_int)ent );
  718. -    out_count++;
  719. -    output( (code_int)-1 );
  720. -
  721. -    /*
  722. -     * Print out stats on stderr
  723. -     */
  724. -    if(zcat_flg == 0 && !quiet) {
  725. -#ifdef DEBUG
  726. -    fprintf( stderr,
  727. -        "%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
  728. -        in_count, out_count, bytes_out );
  729. -    prratio( stderr, in_count, bytes_out );
  730. -    fprintf( stderr, "\n");
  731. -    fprintf( stderr, "\tCompression as in compact: " );
  732. -    prratio( stderr, in_count-bytes_out, in_count );
  733. -    fprintf( stderr, "\n");
  734. -    fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
  735. -        free_ent - 1, n_bits );
  736. -#else /* !DEBUG */
  737. -    fprintf( stderr, "Compression: " );
  738. -    prratio( stderr, in_count-bytes_out, in_count );
  739. -#endif /* DEBUG */
  740. -    }
  741. -    if(bytes_out > in_count)    /* exit(2) if no savings */
  742. -    exit_stat = 2;
  743. -    return;
  744. -}
  745. -
  746. -/*****************************************************************
  747. - * TAG( output )
  748. - *
  749. - * Output the given code.
  750. - * Inputs:
  751. - *     code:    A n_bits-bit integer.  If == -1, then EOF.  This assumes
  752. - *        that n_bits =< (long)wordsize - 1.
  753. - * Outputs:
  754. - *     Outputs code to the file.
  755. - * Assumptions:
  756. - *    Chars are 8 bits long.
  757. - * Algorithm:
  758. - *     Maintain a BITS character long buffer (so that 8 codes will
  759. - * fit in it exactly).  Use the VAX insv instruction to insert each
  760. - * code in turn.  When the buffer fills up empty it and start over.
  761. - */
  762. -
  763. -static char buf[BITS];
  764. -
  765. -#ifndef vax
  766. -char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
  767. -char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
  768. -#endif /* vax */
  769. -
  770. -output( code )
  771. -code_int  code;
  772. -{
  773. -#ifdef DEBUG
  774. -    static int col = 0;
  775. -#endif /* DEBUG */
  776. -
  777. -    /*
  778. -     * On the VAX, it is important to have the register declarations
  779. -     * in exactly the order given, or the asm will break.
  780. -     */
  781. -    register int r_off = offset, bits= n_bits;
  782. -    register char * bp = buf;
  783. -
  784. -#ifdef DEBUG
  785. -    if ( verbose )
  786. -        fprintf( stderr, "%5d%c", code,
  787. -            (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
  788. -#endif /* DEBUG */
  789. -    if ( code >= 0 ) {
  790. -#ifdef vax
  791. -    /* VAX DEPENDENT!! Implementation on other machines is below.
  792. -     *
  793. -     * Translation: Insert BITS bits from the argument starting at
  794. -     * offset bits from the beginning of buf.
  795. -     */
  796. -    0;    /* Work around for pcc -O bug with asm and if stmt */
  797. -    asm( "insv    4(ap),r11,r10,(r9)" );
  798. -#else /* not a vax */
  799. -/* 
  800. - * byte/bit numbering on the VAX is simulated by the following code
  801. - */
  802. -    /*
  803. -     * Get to the first byte.
  804. -     */
  805. -    bp += (r_off >> 3);
  806. -    r_off &= 7;
  807. -    /*
  808. -     * Since code is always >= 8 bits, only need to mask the first
  809. -     * hunk on the left.
  810. -     */
  811. -    *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
  812. -    bp++;
  813. -    bits -= (8 - r_off);
  814. -    code >>= 8 - r_off;
  815. -    /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
  816. -    if ( bits >= 8 ) {
  817. -        *bp++ = code;
  818. -        code >>= 8;
  819. -        bits -= 8;
  820. -    }
  821. -    /* Last bits. */
  822. -    if(bits)
  823. -        *bp = code;
  824. -#endif /* vax */
  825. -    offset += n_bits;
  826. -    if ( offset == (n_bits << 3) ) {
  827. -        bp = buf;
  828. -        bits = n_bits;
  829. -        bytes_out += bits;
  830. -        do
  831. -        putchar(*bp++);
  832. -        while(--bits);
  833. -        offset = 0;
  834. -    }
  835. -
  836. -    /*
  837. -     * If the next entry is going to be too big for the code size,
  838. -     * then increase it, if possible.
  839. -     */
  840. -    if ( free_ent > maxcode || (clear_flg > 0))
  841. -    {
  842. -        /*
  843. -         * Write the whole buffer, because the input side won't
  844. -         * discover the size increase until after it has read it.
  845. -         */
  846. -        if ( offset > 0 ) {
  847. -        if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
  848. -            writeerr();
  849. -        bytes_out += n_bits;
  850. -        }
  851. -        offset = 0;
  852. -
  853. -        if ( clear_flg ) {
  854. -                maxcode = MAXCODE (n_bits = INIT_BITS);
  855. -            clear_flg = 0;
  856. -        }
  857. -        else {
  858. -            n_bits++;
  859. -            if ( n_bits == maxbits )
  860. -            maxcode = maxmaxcode;
  861. -            else
  862. -            maxcode = MAXCODE(n_bits);
  863. -        }
  864. -#ifdef DEBUG
  865. -        if ( debug ) {
  866. -        fprintf( stderr, "\nChange to %d bits\n", n_bits );
  867. -        col = 0;
  868. -        }
  869. -#endif /* DEBUG */
  870. -    }
  871. -    } else {
  872. -    /*
  873. -     * At EOF, write the rest of the buffer.
  874. -     */
  875. -    if ( offset > 0 )
  876. -        fwrite( buf, 1, (offset + 7) / 8, stdout );
  877. -    bytes_out += (offset + 7) / 8;
  878. -    offset = 0;
  879. -    fflush( stdout );
  880. -#ifdef DEBUG
  881. -    if ( verbose )
  882. -        fprintf( stderr, "\n" );
  883. -#endif /* DEBUG */
  884. -    if( ferror( stdout ) )
  885. -        writeerr();
  886. -    }
  887. -}
  888. -
  889. -/*
  890. - * Decompress stdin to stdout.  This routine adapts to the codes in the
  891. - * file building the "string" table on-the-fly; requiring no table to
  892. - * be stored in the compressed file.  The tables used herein are shared
  893. - * with those of the compress() routine.  See the definitions above.
  894. - */
  895. -
  896. -decompress() {
  897. -    register char_type *stackp;
  898. -    register int finchar;
  899. -    register code_int code, oldcode, incode;
  900. -
  901. -    /*
  902. -     * As above, initialize the first 256 entries in the table.
  903. -     */
  904. -    maxcode = MAXCODE(n_bits = INIT_BITS);
  905. -    for ( code = 255; code >= 0; code-- ) {
  906. -    tab_prefixof(code) = 0;
  907. -    tab_suffixof(code) = (char_type)code;
  908. -    }
  909. -    free_ent = ((block_compress) ? FIRST : 256 );
  910. -
  911. -    finchar = oldcode = getcode();
  912. -    if(oldcode == -1)    /* EOF already? */
  913. -    return;            /* Get out of here */
  914. -    putchar( (char)finchar );        /* first code must be 8 bits = char */
  915. -    if(ferror(stdout))        /* Crash if can't write */
  916. -    writeerr();
  917. -    stackp = de_stack;
  918. -
  919. -    while ( (code = getcode()) > -1 ) {
  920. -
  921. -    if ( (code == CLEAR) && block_compress ) {
  922. -        for ( code = 255; code >= 0; code-- )
  923. -        tab_prefixof(code) = 0;
  924. -        clear_flg = 1;
  925. -        free_ent = FIRST - 1;
  926. -        if ( (code = getcode ()) == -1 )    /* O, untimely death! */
  927. -        break;
  928. -    }
  929. -    incode = code;
  930. -    /*
  931. -     * Special case for KwKwK string.
  932. -     */
  933. -    if ( code >= free_ent ) {
  934. -            *stackp++ = finchar;
  935. -        code = oldcode;
  936. -    }
  937. -
  938. -    /*
  939. -     * Generate output characters in reverse order
  940. -     */
  941. -#ifdef SIGNED_COMPARE_SLOW
  942. -    while ( ((unsigned long)code) >= ((unsigned long)256) ) {
  943. -#else
  944. -    while ( code >= 256 ) {
  945. -#endif
  946. -        *stackp++ = tab_suffixof(code);
  947. -        code = tab_prefixof(code);
  948. -    }
  949. -    *stackp++ = finchar = tab_suffixof(code);
  950. -
  951. -    /*
  952. -     * And put them out in forward order
  953. -     */
  954. -    do
  955. -        putchar ( *--stackp );
  956. -    while ( stackp > de_stack );
  957. -
  958. -    /*
  959. -     * Generate the new entry.
  960. -     */
  961. -    if ( (code=free_ent) < maxmaxcode ) {
  962. -        tab_prefixof(code) = (unsigned short)oldcode;
  963. -        tab_suffixof(code) = finchar;
  964. -        free_ent = code+1;
  965. -    } 
  966. -    /*
  967. -     * Remember previous code.
  968. -     */
  969. -    oldcode = incode;
  970. -    }
  971. -    fflush( stdout );
  972. -    if(ferror(stdout))
  973. -    writeerr();
  974. -}
  975. -
  976. -/*****************************************************************
  977. - * TAG( getcode )
  978. - *
  979. - * Read one code from the standard input.  If EOF, return -1.
  980. - * Inputs:
  981. - *     stdin
  982. - * Outputs:
  983. - *     code or -1 is returned.
  984. - */
  985. -
  986. -code_int
  987. -getcode() {
  988. -    /*
  989. -     * On the VAX, it is important to have the register declarations
  990. -     * in exactly the order given, or the asm will break.
  991. -     */
  992. -    register code_int code;
  993. -    static int offset = 0, size = 0;
  994. -    static char_type buf[BITS];
  995. -    register int r_off, bits;
  996. -    register char_type *bp = buf;
  997. -
  998. -    if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
  999. -    /*
  1000. -     * If the next entry will be too big for the current code
  1001. -     * size, then we must increase the size.  This implies reading
  1002. -     * a new buffer full, too.
  1003. -     */
  1004. -    if ( free_ent > maxcode ) {
  1005. -        n_bits++;
  1006. -        if ( n_bits == maxbits )
  1007. -        maxcode = maxmaxcode;    /* won't get any bigger now */
  1008. -        else
  1009. -        maxcode = MAXCODE(n_bits);
  1010. -    }
  1011. -    if ( clear_flg > 0) {
  1012. -            maxcode = MAXCODE (n_bits = INIT_BITS);
  1013. -        clear_flg = 0;
  1014. -    }
  1015. -    size = fread( buf, 1, n_bits, stdin );
  1016. -    if ( size <= 0 )
  1017. -        return -1;            /* end of file */
  1018. -    offset = 0;
  1019. -    /* Round size down to integral number of codes */
  1020. -    size = (size << 3) - (n_bits - 1);
  1021. -    }
  1022. -    r_off = offset;
  1023. -    bits = n_bits;
  1024. -#ifdef vax
  1025. -    asm( "extzv   r10,r9,(r8),r11" );
  1026. -#else /* not a vax */
  1027. -    /*
  1028. -     * Get to the first byte.
  1029. -     */
  1030. -    bp += (r_off >> 3);
  1031. -    r_off &= 7;
  1032. -    /* Get first part (low order bits) */
  1033. -#ifdef NO_UCHAR
  1034. -    code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
  1035. -#else
  1036. -    code = (*bp++ >> r_off);
  1037. -#endif /* NO_UCHAR */
  1038. -    bits -= (8 - r_off);
  1039. -    r_off = 8 - r_off;        /* now, offset into code word */
  1040. -    /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
  1041. -    if ( bits >= 8 ) {
  1042. -#ifdef NO_UCHAR
  1043. -        code |= (*bp++ & 0xff) << r_off;
  1044. -#else
  1045. -        code |= *bp++ << r_off;
  1046. -#endif /* NO_UCHAR */
  1047. -        r_off += 8;
  1048. -        bits -= 8;
  1049. -    }
  1050. -    /* high order bits. */
  1051. -    code |= (*bp & rmask[bits]) << r_off;
  1052. -#endif /* vax */
  1053. -    offset += n_bits;
  1054. -
  1055. -    return code;
  1056. -}
  1057. -
  1058. -char *
  1059. -rindex(s, c)        /* For those who don't have it in libc.a */
  1060. -register char *s, c;
  1061. -{
  1062. -    char *p;
  1063. -    for (p = NULL; *s; s++)
  1064. -        if (*s == c)
  1065. -        p = s;
  1066. -    return(p);
  1067. -}
  1068. -
  1069. -#ifdef DEBUG
  1070. -printcodes()
  1071. -{
  1072. -    /*
  1073. -     * Just print out codes from input file.  For debugging.
  1074. -     */
  1075. -    code_int code;
  1076. -    int col = 0, bits;
  1077. -
  1078. -    bits = n_bits = INIT_BITS;
  1079. -    maxcode = MAXCODE(n_bits);
  1080. -    free_ent = ((block_compress) ? FIRST : 256 );
  1081. -    while ( ( code = getcode() ) >= 0 ) {
  1082. -    if ( (code == CLEAR) && block_compress ) {
  1083. -           free_ent = FIRST - 1;
  1084. -           clear_flg = 1;
  1085. -    }
  1086. -    else if ( free_ent < maxmaxcode )
  1087. -        free_ent++;
  1088. -    if ( bits != n_bits ) {
  1089. -        fprintf(stderr, "\nChange to %d bits\n", n_bits );
  1090. -        bits = n_bits;
  1091. -        col = 0;
  1092. -    }
  1093. -    fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
  1094. -    }
  1095. -    putc( '\n', stderr );
  1096. -    exit( 0 );
  1097. -}
  1098. -
  1099. -#ifdef XENIX_16
  1100. -code_int stab1[8192] ;
  1101. -code_int stab2[8192] ;
  1102. -code_int stab3[8192] ;
  1103. -code_int stab4[8192] ;
  1104. -code_int stab5[8192] ;
  1105. -code_int stab6[8192] ;
  1106. -code_int stab7[8192] ;
  1107. -code_int stab8[8192] ;
  1108. -code_int * sorttab[8] = {stab1, stab2, stab3, stab4, stab5, stab6, stab7,
  1109. -                         stab8 } ;
  1110. -#define stabof(i) (sorttab[(i) >> 13][(i) & 0x1fff]) 
  1111. -#else
  1112. -code_int sorttab[SSIZE];    /* sorted pointers into htab */
  1113. -#define stabof(i) (sorttab[i])
  1114. -#endif
  1115. -
  1116. -dump_tab()    /* dump string table */
  1117. -{
  1118. -    register int i, first;
  1119. -    register ent;
  1120. -#define STACK_SIZE    15000
  1121. -    int stack_top = STACK_SIZE;
  1122. -    register c;
  1123. -    unsigned mbshift ;
  1124. -
  1125. -    if(do_decomp == 0) {    /* compressing */
  1126. -    register int flag = 1;
  1127. -
  1128. -    for(i=0; i<hsize; i++) {    /* build sort pointers */
  1129. -        if((long)htabof(i) >= 0) {
  1130. -            stabof(codetabof(i)) = i;
  1131. -        }
  1132. -    }
  1133. -    first = block_compress ? FIRST : 256;
  1134. -    for(i = first; i < free_ent; i++) {
  1135. -        fprintf(stderr, "%5d: \"", i);
  1136. -        de_stack[--stack_top] = '\n';
  1137. -        de_stack[--stack_top] = '"';
  1138. -        stack_top = in_stack((htabof(stabof(i))>>maxbits)&0xff, 
  1139. -                                     stack_top);
  1140. -/*        for(ent=htabof(stabof(i)) & ((1<<maxbits)-1); */
  1141. -        mbshift = ((1 << maxbits) - 1) ;
  1142. -        ent = htabof(stabof(i)) & mbshift ;
  1143. -        for(;
  1144. -            ent > 256;
  1145. -            /* ent=htabof(stabof(ent)) & ((1<<maxbits)-1)) { */
  1146. -            ent=htabof(stabof(ent)) & mbshift) {
  1147. -            stack_top = in_stack(htabof(stabof(ent)) >> maxbits,
  1148. -                        stack_top);
  1149. -        }
  1150. -        stack_top = in_stack(ent, stack_top);
  1151. -        fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr);
  1152. -           stack_top = STACK_SIZE;
  1153. -    }
  1154. -   } else if(!debug) {    /* decompressing */
  1155. -
  1156. -       for ( i = 0; i < free_ent; i++ ) {
  1157. -       ent = i;
  1158. -       c = tab_suffixof(ent);
  1159. -       if ( isascii(c) && isprint(c) )
  1160. -           fprintf( stderr, "%5d: %5d/'%c'  \"",
  1161. -               ent, tab_prefixof(ent), c );
  1162. -       else
  1163. -           fprintf( stderr, "%5d: %5d/\\%03o \"",
  1164. -               ent, tab_prefixof(ent), c );
  1165. -       de_stack[--stack_top] = '\n';
  1166. -       de_stack[--stack_top] = '"';
  1167. -       for ( ; ent != NULL;
  1168. -           ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
  1169. -           stack_top = in_stack(tab_suffixof(ent), stack_top);
  1170. -       }
  1171. -       fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr );
  1172. -       stack_top = STACK_SIZE;
  1173. -       }
  1174. -    }
  1175. -}
  1176. -
  1177. -int
  1178. -in_stack(c, stack_top)
  1179. -    register c, stack_top;
  1180. -{
  1181. -    if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
  1182. -        de_stack[--stack_top] = c;
  1183. -    } else {
  1184. -        switch( c ) {
  1185. -        case '\n': de_stack[--stack_top] = 'n'; break;
  1186. -        case '\t': de_stack[--stack_top] = 't'; break;
  1187. -        case '\b': de_stack[--stack_top] = 'b'; break;
  1188. -        case '\f': de_stack[--stack_top] = 'f'; break;
  1189. -        case '\r': de_stack[--stack_top] = 'r'; break;
  1190. -        case '\\': de_stack[--stack_top] = '\\'; break;
  1191. -        default:
  1192. -         de_stack[--stack_top] = '0' + c % 8;
  1193. -         de_stack[--stack_top] = '0' + (c / 8) % 8;
  1194. -         de_stack[--stack_top] = '0' + c / 64;
  1195. -         break;
  1196. -        }
  1197. -        de_stack[--stack_top] = '\\';
  1198. -    }
  1199. -    return stack_top;
  1200. -}
  1201. -#endif /* DEBUG */
  1202. -
  1203. -writeerr()
  1204. -{
  1205. -    perror ( ofname );
  1206. -    unlink ( ofname );
  1207. -    exit ( 1 );
  1208. -}
  1209. -
  1210. -copystat(ifname, ofname)
  1211. -char *ifname, *ofname;
  1212. -{
  1213. -    struct stat statbuf;
  1214. -    int mode;
  1215. -    time_t timep[2];
  1216. -
  1217. -    fclose(stdout);
  1218. -    if (stat(ifname, &statbuf)) {        /* Get stat on input file */
  1219. -    perror(ifname);
  1220. -    return;
  1221. -    }
  1222. -    if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
  1223. -    if(quiet)
  1224. -            fprintf(stderr, "%s: ", ifname);
  1225. -    fprintf(stderr, " -- not a regular file: unchanged");
  1226. -    exit_stat = 1;
  1227. -    } else if (statbuf.st_nlink > 1) {
  1228. -    if(quiet)
  1229. -            fprintf(stderr, "%s: ", ifname);
  1230. -    fprintf(stderr, " -- has %d other links: unchanged",
  1231. -        statbuf.st_nlink - 1);
  1232. -    exit_stat = 1;
  1233. -    } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
  1234. -    if(!quiet)
  1235. -        fprintf(stderr, " -- file unchanged");
  1236. -    } else {            /* ***** Successful Compression ***** */
  1237. -    exit_stat = 0;
  1238. -    mode = statbuf.st_mode & 07777;
  1239. -    if (chmod(ofname, mode))        /* Copy modes */
  1240. -        perror(ofname);
  1241. -    chown(ofname, statbuf.st_uid, statbuf.st_gid);    /* Copy ownership */
  1242. -    timep[0] = statbuf.st_atime;
  1243. -    timep[1] = statbuf.st_mtime;
  1244. -    utime(ofname, timep);    /* Update last accessed and modified times */
  1245. -    if (unlink(ifname))    /* Remove input file */
  1246. -        perror(ifname);
  1247. -    if(!quiet)
  1248. -        fprintf(stderr, " -- replaced with %s", ofname);
  1249. -    return;        /* Successful return */
  1250. -    }
  1251. -
  1252. -    /* Unsuccessful return -- one of the tests failed */
  1253. -    if (unlink(ofname))
  1254. -    perror(ofname);
  1255. -}
  1256. -/*
  1257. - * This routine returns 1 if we are running in the foreground and stderr
  1258. - * is a tty.
  1259. - */
  1260. -foreground()
  1261. -{
  1262. -    if(bgnd_flag) {    /* background? */
  1263. -        return(0);
  1264. -    } else {            /* foreground */
  1265. -        if(isatty(2)) {        /* and stderr is a tty */
  1266. -            return(1);
  1267. -        } else {
  1268. -            return(0);
  1269. -        }
  1270. -    }
  1271. -}
  1272. -
  1273. -onintr ( )
  1274. -{
  1275. -    unlink ( ofname );
  1276. -    exit ( 1 );
  1277. -}
  1278. -
  1279. -oops ( )    /* wild pointer -- assume bad input */
  1280. -{
  1281. -    if ( do_decomp == 1 ) 
  1282. -        fprintf ( stderr, "uncompress: corrupt input\n" );
  1283. -    unlink ( ofname );
  1284. -    exit ( 1 );
  1285. -}
  1286. -
  1287. -cl_block ()        /* table clear for block compress */
  1288. -{
  1289. -    register long int rat;
  1290. -
  1291. -    checkpoint = in_count + CHECK_GAP;
  1292. -#ifdef DEBUG
  1293. -    if ( debug ) {
  1294. -            fprintf ( stderr, "count: %ld, ratio: ", in_count );
  1295. -             prratio ( stderr, in_count, bytes_out );
  1296. -        fprintf ( stderr, "\n");
  1297. -    }
  1298. -#endif /* DEBUG */
  1299. -
  1300. -    if(in_count > 0x007fffff) {    /* shift will overflow */
  1301. -    rat = bytes_out >> 8;
  1302. -    if(rat == 0) {        /* Don't divide by zero */
  1303. -        rat = 0x7fffffff;
  1304. -    } else {
  1305. -        rat = in_count / rat;
  1306. -    }
  1307. -    } else {
  1308. -    rat = (in_count << 8) / bytes_out;    /* 8 fractional bits */
  1309. -    }
  1310. -    if ( rat > ratio ) {
  1311. -    ratio = rat;
  1312. -    } else {
  1313. -    ratio = 0;
  1314. -#ifdef DEBUG
  1315. -    if(verbose)
  1316. -        dump_tab();    /* dump string table */
  1317. -#endif
  1318. -     cl_hash ( (count_int) hsize );
  1319. -    free_ent = FIRST;
  1320. -    clear_flg = 1;
  1321. -    output ( (code_int) CLEAR );
  1322. -#ifdef DEBUG
  1323. -    if(debug)
  1324. -            fprintf ( stderr, "clear\n" );
  1325. -#endif /* DEBUG */
  1326. -    }
  1327. -}
  1328. -
  1329. -cl_hash(hsize)        /* reset code table */
  1330. -    register count_int hsize;
  1331. -{
  1332. -#ifndef XENIX_16    /* Normal machine */
  1333. -    register count_int *htab_p = htab+hsize;
  1334. -#else
  1335. -    register j;
  1336. -    register long k = hsize;
  1337. -    register count_int *htab_p;
  1338. -#endif
  1339. -    register long i;
  1340. -    register long m1 = -1;
  1341. -
  1342. -#ifdef XENIX_16
  1343. -    for(j=0; j<=8 && k>=0; j++,k-=8192) {
  1344. -    i = 8192;
  1345. -    if(k < 8192) {
  1346. -        i = k;
  1347. -    }
  1348. -    htab_p = &(htab[j][i]);
  1349. -    i -= 16;
  1350. -    if(i > 0) {
  1351. -#else
  1352. -    i = hsize - 16;
  1353. -#endif
  1354. -     do {                /* might use Sys V memset(3) here */
  1355. -        *(htab_p-16) = m1;
  1356. -        *(htab_p-15) = m1;
  1357. -        *(htab_p-14) = m1;
  1358. -        *(htab_p-13) = m1;
  1359. -        *(htab_p-12) = m1;
  1360. -        *(htab_p-11) = m1;
  1361. -        *(htab_p-10) = m1;
  1362. -        *(htab_p-9) = m1;
  1363. -        *(htab_p-8) = m1;
  1364. -        *(htab_p-7) = m1;
  1365. -        *(htab_p-6) = m1;
  1366. -        *(htab_p-5) = m1;
  1367. -        *(htab_p-4) = m1;
  1368. -        *(htab_p-3) = m1;
  1369. -        *(htab_p-2) = m1;
  1370. -        *(htab_p-1) = m1;
  1371. -        htab_p -= 16;
  1372. -    } while ((i -= 16) >= 0);
  1373. -#ifdef XENIX_16
  1374. -    }
  1375. -    }
  1376. -#endif
  1377. -        for ( i += 16; i > 0; i-- )
  1378. -        *--htab_p = m1;
  1379. -}
  1380. -
  1381. -prratio(stream, num, den)
  1382. -FILE *stream;
  1383. -long int num, den;
  1384. -{
  1385. -    register int q;            /* Doesn't need to be long */
  1386. -
  1387. -    if(num > 214748L) {        /* 2147483647/10000 */
  1388. -        q = num / (den / 10000L);
  1389. -    } else {
  1390. -        q = 10000L * num / den;        /* Long calculations, though */
  1391. -    }
  1392. -    if (q < 0) {
  1393. -        putc('-', stream);
  1394. -        q = -q;
  1395. -    }
  1396. -    fprintf(stream, "%d.%02d%%", q / 100, q % 100);
  1397. -}
  1398. -
  1399. -version()
  1400. -{
  1401. -    fprintf(stderr, "%s\n", rcs_ident);
  1402. -    fprintf(stderr, "Options: ");
  1403. -#ifdef vax
  1404. -    fprintf(stderr, "vax, ");
  1405. -#endif
  1406. -#ifdef NO_UCHAR
  1407. -    fprintf(stderr, "NO_UCHAR, ");
  1408. -#endif
  1409. -#ifdef SIGNED_COMPARE_SLOW
  1410. -    fprintf(stderr, "SIGNED_COMPARE_SLOW, ");
  1411. -#endif
  1412. -#ifdef XENIX_16
  1413. -    fprintf(stderr, "XENIX_16, ");
  1414. -#endif
  1415. -#ifdef COMPATIBLE
  1416. -    fprintf(stderr, "COMPATIBLE, ");
  1417. -#endif
  1418. -#ifdef DEBUG
  1419. -    fprintf(stderr, "DEBUG, ");
  1420. -#endif
  1421. -#ifdef BSD4_2
  1422. -    fprintf(stderr, "BSD4_2, ");
  1423. -#endif
  1424. -    fprintf(stderr, "BITS = %d\n", BITS);
  1425. -}
  1426. *-*-END-of-src/compress.c-*-*
  1427. echo x - src/virtterm.c 1>&2
  1428. sed 's/.//' >src/virtterm.c <<'*-*-END-of-src/virtterm.c-*-*'
  1429. -/*
  1430. - *  Virtual terminal handler
  1431. - *  Written by Kenneth Almquist, AGS Computers  (HO 4C601, X7105).
  1432. - *  Modified by Stephen Hemminger, to use TERMCAP (without curses)
  1433. - */
  1434. -
  1435. -#ifdef SCCSID
  1436. -static char    *SccsId = "@(#)virtterm.c    1.12    10/29/86";
  1437. -#endif /* SCCSID */
  1438. -
  1439. -/*LINTLIBRARY*/
  1440. -
  1441. -#include <stdio.h>
  1442. -#include <ctype.h>
  1443. -#include <sys/types.h>
  1444. -#include <sys/ioctl.h>
  1445. -#include <signal.h>
  1446. -#ifdef USG
  1447. -#include <termio.h>
  1448. -#else /* !USG */
  1449. -#include <sgtty.h>
  1450. -#endif /* !USG */
  1451. -
  1452. -/*
  1453. - * These values for MAXPLEN and MAXLLEN are used to dimension arrays
  1454. - * that hold strings of relative cursor motions.  The actual arrays that
  1455. - * are used to hold screen images are malloc'd.
  1456. - */
  1457. -#define MAXPLEN 90
  1458. -#define MAXLLEN 160
  1459. -
  1460. -#define BOTLINE (ROWS - 1)
  1461. -#define DIRTY 01
  1462. -
  1463. -/* terminal escape sequences from termcap */
  1464. -#define HO _tstr[0]        /* home */
  1465. -#define CL _tstr[1]        /* clear screen */
  1466. -#define CD _tstr[2]        /* clear to end of screen */
  1467. -#define CE _tstr[3]        /* clear to end of line */
  1468. -#define xUP _tstr[4]        /* up one line */
  1469. -#define DO _tstr[5]        /* down one line */
  1470. -#define US _tstr[6]        /* underline */
  1471. -#define UE _tstr[7]        /* underline end */
  1472. -#define BT _tstr[8]        /* backtab */
  1473. -#define xBC _tstr[9]        /* backspace */
  1474. -#define AL _tstr[10]        /* insert line */
  1475. -#define DL _tstr[11]        /* delete line */
  1476. -#define CM _tstr[12]        /* cursor move */
  1477. -#define CH _tstr[13]        /* cursor horizontal move */
  1478. -#define CV _tstr[14]        /* cursor vertical move */
  1479. -#define CS _tstr[15]        /* scrolling region */
  1480. -#define SF _tstr[16]        /* scroll forwards */
  1481. -#define SR _tstr[17]        /* scroll backwards */
  1482. -#define TI _tstr[18]        /* start cursor mode */
  1483. -#define TE _tstr[19]        /* end cursor mode */
  1484. -#define TA _tstr[20]        /* tab char (if not \t) */
  1485. -#define CR _tstr[21]        /* carriage return (if not \r) */
  1486. -#define xPC _tstr[22]        /* for reading pad character */
  1487. -char PC;            /* pad character */
  1488. -char *BC, *UP;            /* external variables for tgoto */
  1489. -
  1490. -static char sname[] = "hoclcdceupdousuebtbcaldlcmchcvcssfsrtitetacrpc";
  1491. -char *_tstr[23];
  1492. -int     HOlen;            /* length of HO string */
  1493. -
  1494. -
  1495. -/* terminal flags */
  1496. -#define BS _tflg[0]        /* can backspace */
  1497. -#define AM _tflg[1]        /* has auto margins */
  1498. -#define XN _tflg[2]        /* no newline after wrap */
  1499. -#define RET !_tflg[3]        /* has carriage return */
  1500. -#define NS _tflg[4]        /* has SF (scroll forward) */
  1501. -#define PT _tflg[5]        /* has tabs */
  1502. -#define XT _tflg[6]        /* tabs are destructive */
  1503. -int    GT = 1;            /* tab stops on terminal are set */
  1504. -
  1505. -static char bname[] = "bsamxnncnsptxt";
  1506. -char _tflg[7];
  1507. -
  1508. -
  1509. -extern char *tgoto(), *tgetstr();
  1510. -extern char *getenv(), *strcpy();
  1511. -
  1512. -#define ULINE 0200
  1513. -
  1514. -/* Constants accessable by user */
  1515. -int     hasscroll;        /* scrolling type, 0 == no scrolling */
  1516. -int     ROWS;            /* number of lines on screen */
  1517. -int     COLS;            /* width of screen */
  1518. -
  1519. -struct line {
  1520. -    char    len;
  1521. -    char    flags;
  1522. -    char    *l;        /* pointer to actual line text, NO NULL @ end */
  1523. -};
  1524. -
  1525. -int     _row, _col;
  1526. -int     _srow, _scol;
  1527. -struct line *_virt;        /* what we want the screen to look like */
  1528. -struct line *_actual;        /* What it actually looks like */
  1529. -int     _uline = 0;
  1530. -int     _junked = 1;
  1531. -int     _curjunked;
  1532. -int     _dir = 1;
  1533. -int    _shifttop, _shiftbot;
  1534. -int    _shift;
  1535. -int    _scratched;
  1536. -int     vputc();
  1537. -
  1538. -/*
  1539. - * Tell refresh to shift lines in region upwards count lines.  Count
  1540. - * may be negative.  The virtual image is not shifted; this may change
  1541. - * later.  The variable _scratched is set to supress all attempts to
  1542. - * shift.
  1543. - */
  1544. -
  1545. -ushift(top, bot, count)
  1546. -{
  1547. -    if (_scratched)
  1548. -        return;
  1549. -    if (_shift != 0 && (_shifttop != top || _shiftbot != bot)) {
  1550. -        _scratched++;
  1551. -        return;
  1552. -    }
  1553. -    _shifttop = top;
  1554. -    _shiftbot = bot;
  1555. -    _shift += count;
  1556. -}
  1557. -
  1558. -/*
  1559. - * generate a beep on the terminal
  1560. - */
  1561. -beep()
  1562. -{
  1563. -    vputc('\7');
  1564. -}
  1565. -
  1566. -/*
  1567. - * Move to one line below the bottom of the screen.
  1568. - */
  1569. -botscreen()
  1570. -{
  1571. -    _amove(BOTLINE, 0);
  1572. -    vputc('\n');
  1573. -    vflush();
  1574. -}
  1575. -
  1576. -move(row, col)
  1577. -{
  1578. -    if (row < 0 || row >= ROWS || col < 0 || col >= COLS)
  1579. -        return;
  1580. -    _row = row;
  1581. -    _col = col;
  1582. -}
  1583. -
  1584. -
  1585. -
  1586. -/*
  1587. - * Output string at specified location.
  1588. - */
  1589. -mvaddstr(row, col, str)
  1590. -char *str;
  1591. -{
  1592. -    move(row, col);
  1593. -    addstr(str);
  1594. -}
  1595. -
  1596. -addstr(s)
  1597. -char   *s;
  1598. -{
  1599. -    register char  *p;
  1600. -    register struct line   *lp;
  1601. -    register int    col = _col;
  1602. -
  1603. -    lp = &_virt[_row];
  1604. -    if (lp->len < col) {
  1605. -        p = &lp->l[lp->len];
  1606. -        while (lp->len < col) {
  1607. -            *p++ = ' ';
  1608. -            lp->len++;
  1609. -        }
  1610. -    }
  1611. -    for (p = s; *p != '\0'; p++) {
  1612. -        if (*p == '\n') {
  1613. -            lp->len = col;
  1614. -            lp->flags |= DIRTY;
  1615. -            col = 0;
  1616. -            if (++_row >= ROWS)
  1617. -                _row = 0;
  1618. -            lp = &_virt[_row];
  1619. -        }
  1620. -        else {
  1621. -            lp->l[col] = *p;
  1622. -            lp->flags |= DIRTY;
  1623. -            if (++col >= COLS) {
  1624. -                lp->len = COLS;
  1625. -                col = 0;
  1626. -                if (++_row >= ROWS)
  1627. -                    _row = 0;
  1628. -                lp = &_virt[_row];
  1629. -            }
  1630. -        }
  1631. -    }
  1632. -    if (lp->len <= col)
  1633. -        lp->len = col;
  1634. -    _col = col;
  1635. -}
  1636. -
  1637. -addch(c)
  1638. -{
  1639. -    register struct line   *lp;
  1640. -    register char  *p;
  1641. -
  1642. -    lp = &_virt[_row];
  1643. -    if (lp->len < _col) {
  1644. -        p = &lp->l[lp->len];
  1645. -        while (lp->len < _col) {
  1646. -            *p++ = ' ';
  1647. -            lp->len++;
  1648. -        }
  1649. -    }
  1650. -    lp->l[_col] = c;
  1651. -    if (lp->len == _col)
  1652. -        lp->len++;
  1653. -    if (++_col >= COLS) {
  1654. -        _col = 0;
  1655. -        if (++_row >= ROWS)
  1656. -            _row = 0;
  1657. -    }
  1658. -    lp->flags |= DIRTY;
  1659. -}
  1660. -
  1661. -/*
  1662. - * Clear an entire line.
  1663. - */
  1664. -clrline(row)
  1665. -{
  1666. -    register struct line   *lp;
  1667. -
  1668. -    lp = &_virt[row];
  1669. -    if (lp->len > 0) {
  1670. -        lp->len = 0;
  1671. -        lp->flags |= DIRTY;
  1672. -    }
  1673. -}
  1674. -
  1675. -erase()
  1676. -{
  1677. -    register    i;
  1678. -
  1679. -    for (i = 0; i < ROWS; i++) {
  1680. -        _virt[i].len = 0;
  1681. -        _virt[i].flags |= DIRTY;
  1682. -    }
  1683. -}
  1684. -
  1685. -refresh()
  1686. -{
  1687. -    register i;
  1688. -    register char *p, *q;
  1689. -    register int j, len;
  1690. -
  1691. -    if (checkin())
  1692. -        return;
  1693. -    i = 1;
  1694. -    if (_junked) {
  1695. -        _sclear();
  1696. -        _junked = 0;
  1697. -    } else if (! _scratched) {
  1698. -        if (_shift > 0) {
  1699. -            _ushift(_shifttop, _shiftbot, _shift);
  1700. -        } else if (_shift < 0) {
  1701. -            i = _dshift(_shifttop, _shiftbot, -_shift);
  1702. -        } else {
  1703. -            i = _dir;
  1704. -        }
  1705. -    }
  1706. -    _dir = i;
  1707. -    _shift = 0;
  1708. -    if (checkin())
  1709. -        return;
  1710. -    _fixlines();
  1711. -    for (i = _dir > 0 ? 0 : BOTLINE; i >= 0 && i < ROWS; i += _dir) {
  1712. -        if ((_virt[i].flags & DIRTY) == 0)
  1713. -            continue;
  1714. -        _ckclrlin(i);        /* decide whether to do a clear line */
  1715. -                    /* probably should consider cd too  */
  1716. -        len = _virt[i].len;
  1717. -        if (_actual[i].len < len)
  1718. -            len = _actual[i].len;
  1719. -        p = _virt[i].l;
  1720. -        q = _actual[i].l;
  1721. -        for (j = 0; j < len; j++) {
  1722. -            if (*p != *q) {
  1723. -                /* Inline test for speed */
  1724. -                if (i != _srow || j != _scol || _curjunked)
  1725. -                    _amove(i, j);
  1726. -                _aputc(*p);
  1727. -                *q = *p;
  1728. -            }
  1729. -            p++;
  1730. -            q++;
  1731. -        }
  1732. -        len = _virt[i].len;
  1733. -        if (_actual[i].len > len) {
  1734. -            _clrtoeol(i, len);
  1735. -        } else {
  1736. -            for (; j < len; j++) {
  1737. -                if (*p != ' ') {
  1738. -                    /* Inline test for speed */
  1739. -                    if (i != _srow || j != _scol || _curjunked)
  1740. -                        _amove(i, j);
  1741. -                    _aputc(*p);
  1742. -                }
  1743. -                *q++ = *p++;
  1744. -            }
  1745. -            _actual[i].len = len;
  1746. -        }
  1747. -        if (checkin())
  1748. -            return;
  1749. -    }
  1750. -    _dir = 1;
  1751. -    _amove(_row, _col);
  1752. -    vflush();            /* flush output buffer */
  1753. -    _scratched = 0;
  1754. -}
  1755. -
  1756. -_dshift(top, bot, count)
  1757. -{
  1758. -    register    i;
  1759. -
  1760. -    if (count >= bot - top || hasscroll < 4) {  /* must have CS or AL/DL */
  1761. -        _scratched++;
  1762. -        return 1;
  1763. -    }
  1764. -    for (i = bot - count; _actual[i].len == 0; i--)
  1765. -        if (i == top)
  1766. -            return 1;
  1767. -    for (i = top; i <= bot; i++)
  1768. -        _virt[i].flags |= DIRTY;
  1769. -    for (i = bot; i >= top + count; i--) {
  1770. -        /* FIXME, this should be done by recirculating the pointers */
  1771. -        register j;
  1772. -        j =     _actual[i].len   = _actual[i - count].len;
  1773. -                _actual[i].flags = _actual[i - count].flags;
  1774. -        strncpy(_actual[i].l,      _actual[i - count].l, j);
  1775. -    }
  1776. -    for (; i >= top; i--)
  1777. -        _actual[i].len = 0;
  1778. -
  1779. -    if (hasscroll != 5) {        /* can we define scrolling region, and scroll back */
  1780. -        tputs(tgoto(CS, bot, top), 1, vputc);/* define scroll region */
  1781. -        _curjunked = 1;
  1782. -        _amove(top, 0);
  1783. -        for (i = count; --i >= 0;)
  1784. -            tputs(SR, 1, vputc);/* scroll back */
  1785. -        tputs(tgoto(CS, BOTLINE, 0), 1, vputc);
  1786. -        _curjunked = 1;
  1787. -    } else {
  1788. -        _amove(bot - count + 1, 0);
  1789. -        if (CD && bot == BOTLINE)
  1790. -            tputs(CD, 1, vputc);
  1791. -        else {
  1792. -            for (i = count; --i >= 0;)
  1793. -                tputs(DL, ROWS - _srow, vputc);
  1794. -        }
  1795. -        _amove(top, 0);
  1796. -        for (i = count; --i >= 0;)
  1797. -            tputs(AL, ROWS - _srow, vputc);
  1798. -    }
  1799. -    return -1;
  1800. -}
  1801. -
  1802. -
  1803. -_ushift(top, bot, count)
  1804. -{
  1805. -    register    i;
  1806. -
  1807. -    if (count >= bot - top || hasscroll == 0) {
  1808. -        _scratched++;
  1809. -        return;
  1810. -    }
  1811. -    for (i = top + count; _actual[i].len == 0; i++)
  1812. -        if (i == bot)
  1813. -            return;
  1814. -    if (hasscroll == 1 || hasscroll == 3) {
  1815. -        /* we cheat and shift the entire screen */
  1816. -        /* be sure we are shifting more lines into than out of position */
  1817. -        if ((bot - top + 1) - count <= ROWS - (bot - top + 1))
  1818. -            return;
  1819. -        top = 0, bot = BOTLINE;
  1820. -    }
  1821. -    for (i = top; i <= bot; i++)
  1822. -        _virt[i].flags |= DIRTY;
  1823. -    for (i = top; i <= bot - count; i++) {
  1824. -        /* FIXME, this should be done by recirculating the pointers */
  1825. -        register int j;
  1826. -        j =     _actual[i].len   = _actual[i + count].len;
  1827. -                _actual[i].flags = _actual[i + count].flags;
  1828. -        strncpy(_actual[i].l,      _actual[i + count].l, j);
  1829. -    }
  1830. -      for (; i <= bot; i++)
  1831. -    for (; i <= bot; i++)
  1832. -        _actual[i].len = 0;
  1833. -
  1834. -    if (hasscroll != 5) {
  1835. -        if (top != 0 || bot != BOTLINE) {
  1836. -            tputs(tgoto(CS, bot, top), 0, vputc);
  1837. -            _curjunked = 1;
  1838. -        }
  1839. -        _amove(bot, 0);    /* move to bottom */
  1840. -        for (i = 0; i < count; i++) {
  1841. -            if (SF)        /* scroll forward */
  1842. -                tputs(SF, 1, vputc);
  1843. -            else
  1844. -                vputc('\n');
  1845. -        }
  1846. -        if (top != 0 || bot != BOTLINE) {
  1847. -            tputs(tgoto(CS, BOTLINE, 0), 0, vputc);
  1848. -            _curjunked = 1;
  1849. -        }
  1850. -    } else {
  1851. -        _amove(top, 0);
  1852. -        for (i = count; --i >= 0;)
  1853. -            tputs(DL, ROWS - _srow, vputc);
  1854. -        if (bot < BOTLINE) {
  1855. -            _amove(bot - count + 1, 0);
  1856. -            for (i = count; --i >= 0;)
  1857. -                tputs(AL, ROWS - _srow, vputc);
  1858. -        }
  1859. -    }
  1860. -}
  1861. -
  1862. -_sclear()
  1863. -{
  1864. -    register struct line   *lp;
  1865. -
  1866. -    tputs(CL, 0, vputc);
  1867. -    _srow = _scol = 0;
  1868. -    for (lp = _actual; lp < &_actual[ROWS]; lp++) {
  1869. -        lp->len = 0;
  1870. -    }
  1871. -    for (lp = _virt; lp < &_virt[ROWS]; lp++) {
  1872. -        if (lp->len != 0)
  1873. -            lp->flags |= DIRTY;
  1874. -    }
  1875. -}
  1876. -
  1877. -_clrtoeol(row, col)
  1878. -{
  1879. -    register struct line *lp = &_actual[row];
  1880. -    register i;
  1881. -
  1882. -    if (CE && lp->len > col + 1) {
  1883. -        _amove(row, col);
  1884. -        tputs(CE, 1, vputc);
  1885. -    } else {
  1886. -        for (i = col ; i < lp->len ; i++) {
  1887. -            if (lp->l[i] != ' ') {
  1888. -                _amove(row, i);
  1889. -                _aputc(' ');
  1890. -            }
  1891. -        }
  1892. -    }
  1893. -    lp->len = col;
  1894. -}
  1895. -
  1896. -_fixlines()
  1897. -{
  1898. -    register struct line   *lp;
  1899. -    register char  *p;
  1900. -    register int    i;
  1901. -
  1902. -    for (i = 0; i < ROWS; i++) {
  1903. -        lp = &_virt[i];
  1904. -        if (lp->flags & DIRTY) {
  1905. -            for (p = &lp->l[lp->len]; --p >= lp->l && *p == ' ';)
  1906. -                ;
  1907. -            lp->len = (int) (p - lp->l) + 1;
  1908. -            if (lp->len == _actual[i].len && strncmp(lp->l, _actual[i].l, lp->len) == 0)
  1909. -                lp->flags &= ~DIRTY;
  1910. -        }
  1911. -    }
  1912. -}
  1913. -
  1914. -
  1915. -/*
  1916. - * Consider clearing the line before overwriting it.
  1917. - * We always clear a line if it has underlined characters in it
  1918. - * because these can cause problems.  Otherwise decide whether
  1919. - * that will decrease the number of characters to change.  This
  1920. - * routine could probably be simplified with no great loss.
  1921. - */
  1922. -
  1923. -_ckclrlin(i)
  1924. -{
  1925. -    int     eval;
  1926. -    int     len;
  1927. -    int     first;
  1928. -    register struct line   *vp, *ap;
  1929. -    register int    j;
  1930. -
  1931. -    if (!CE)
  1932. -        return;
  1933. -    ap = &_actual[i];
  1934. -    vp = &_virt[i];
  1935. -    len = ap->len;
  1936. -    eval = -strlen(CE);
  1937. -    if (len > vp->len) {
  1938. -        len = vp->len;
  1939. -        eval = 0;
  1940. -    }
  1941. -    for (j = 0; j < len && vp->l[j] == ap->l[j]; j++)
  1942. -        ;
  1943. -    if (j == len)
  1944. -        return;
  1945. -    first = j;
  1946. -    while (j < len) {
  1947. -        if (vp->l[j] == ' ') {
  1948. -            if (ap->l[j] != ' ') {
  1949. -                while (++j < len && vp->l[j] == ' ' && ap->l[j] != ' ') {
  1950. -                    eval++;
  1951. -                }
  1952. -                if (j == len)
  1953. -                    eval++;
  1954. -                continue;
  1955. -            }
  1956. -        }
  1957. -        else {
  1958. -            if (vp->l[j] == ap->l[j]) {
  1959. -                while (++j < len && vp->l[j] == ap->l[j]) {
  1960. -                    eval--;
  1961. -                }
  1962. -                continue;
  1963. -            }
  1964. -        }
  1965. -        j++;
  1966. -    }
  1967. -    if (US) {
  1968. -        for (j = 0 ; j < ap->len ; j++) {
  1969. -            if (ap->l[j] & ULINE) {
  1970. -                eval = 999;
  1971. -                if (first > j)
  1972. -                    first = j;
  1973. -                break;
  1974. -            }
  1975. -        }
  1976. -    }
  1977. -    for (j = first; --j >= 0;)
  1978. -        if (vp->l[j] != ' ')
  1979. -            break;
  1980. -    if (j < 0)
  1981. -        first = 0;
  1982. -    if (eval > 0) {
  1983. -        _amove(i, first);
  1984. -        tputs(CE, 0, vputc);
  1985. -        _actual[i].len = first;
  1986. -    }
  1987. -}
  1988. -
  1989. -
  1990. -
  1991. -/*
  1992. - * Move routine
  1993. - *     first compute direct cursor address string and cost
  1994. - *    then relative motion string and cost,
  1995. - *    then home then relative and cost
  1996. - *    choose smallest and do it.
  1997. - *
  1998. - *    The plod stuff is to build the strings (with padding) then decide
  1999. - */
  2000. -static char *plodstr;        /* current location in relmove string */
  2001. -
  2002. -plodput(c)
  2003. -{
  2004. -    *plodstr++ = c;
  2005. -}
  2006. -
  2007. -/* FIXME: speedup 1-char horiz moves:  print the char that's there. */
  2008. -/* FIXME: avoid funniness if cm works. */
  2009. -/* FIXME: Avoid setul(0) if cursor motion OK in standout (XM?) */
  2010. -_amove(row, col)
  2011. -{
  2012. -    char direct[20];
  2013. -    char rel[MAXPLEN*10 + MAXLLEN*10];    /* longest move is full screen */
  2014. -    char ho[MAXPLEN*10 + MAXLLEN*10];
  2015. -    int cost, newcost;
  2016. -    register char *movstr;
  2017. -
  2018. -    if (row == _srow && col == _scol && _curjunked == 0)
  2019. -        return;
  2020. -    if (_uline)
  2021. -        _setul(0);    /* Inline test for speed */
  2022. -
  2023. -    cost = 999;
  2024. -    if (CM) {
  2025. -        plodstr = direct;
  2026. -        tputs(tgoto(CM, col, row), 0, plodput);
  2027. -        cost = plodstr - direct;
  2028. -        movstr = direct;
  2029. -    }
  2030. -    if (_curjunked == 0) {
  2031. -        plodstr = rel;
  2032. -        if (_vmove(_srow, row) >= 0
  2033. -         && (plodstr - rel) < cost        /* after vmove */
  2034. -         && _hmove(_scol, col, row) >= 0
  2035. -         && (newcost = plodstr - rel) < cost) { /* after both */
  2036. -            cost = newcost;
  2037. -            movstr = rel;
  2038. -        }
  2039. -    }
  2040. -    if (cost > HOlen) {    /* is it worth calculating */
  2041. -        plodstr = ho;
  2042. -        tputs(HO, 0, plodput);
  2043. -        if (_vmove(0, row) >= 0
  2044. -         && (plodstr - ho) < cost        /* after ho, vmove */
  2045. -         && _hmove(0, col, row) >= 0
  2046. -         && (newcost = plodstr - ho) < cost) {    /* after all three */
  2047. -            cost = newcost;
  2048. -            movstr = ho;
  2049. -        }
  2050. -    }
  2051. -
  2052. -    if (cost < 999)
  2053. -        while (--cost >= 0)
  2054. -            vputc(*movstr++);
  2055. -
  2056. -    _srow = row;
  2057. -    _scol = col;
  2058. -    _curjunked = 0;
  2059. -}
  2060. -
  2061. -_vmove(orow, nrow)
  2062. -{
  2063. -    char direct[128];
  2064. -    char *saveplod = plodstr;
  2065. -
  2066. -    if (CV) {
  2067. -        plodstr = direct;
  2068. -        tputs(tgoto(CV, nrow, nrow), 0, plodput);
  2069. -        *plodstr = '\0';
  2070. -        plodstr = saveplod;
  2071. -    }
  2072. -    if (orow > nrow) {        /* cursor up */
  2073. -        if (! UP)
  2074. -            return -1;
  2075. -        while (orow > nrow) {
  2076. -            tputs(UP, 1, plodput);
  2077. -            orow--;
  2078. -        }
  2079. -    }
  2080. -    while (orow < nrow) {        /* cursor down */
  2081. -        if (DO)
  2082. -            tputs(DO, 1, plodput);
  2083. -        else
  2084. -            *plodstr++ = '\n';
  2085. -        orow++;
  2086. -    }
  2087. -    if (CV && plodstr - saveplod >= strlen(direct)) {
  2088. -        register char *p;
  2089. -        plodstr = saveplod;
  2090. -        for (p = direct ; *plodstr = *p++ ; plodstr++)
  2091. -            ;
  2092. -    }
  2093. -    return 0;
  2094. -}
  2095. -
  2096. -_hmove(ocol, ncol, row)
  2097. -{
  2098. -    char direct[128];
  2099. -    char ret[MAXLLEN*10];
  2100. -    char *saveplod = plodstr;
  2101. -    char *movstr;
  2102. -    int cost, newcost;
  2103. -
  2104. -    cost = 999;
  2105. -    if (CH) {
  2106. -        plodstr = direct;
  2107. -        tputs(tgoto(CH, ncol, ncol), 0, plodput);
  2108. -        cost = plodstr - direct;
  2109. -        movstr = direct;
  2110. -        plodstr = saveplod;
  2111. -    }
  2112. -    if (RET && ocol > ncol) {    /* consider doing carriage return */
  2113. -        plodstr = ret;
  2114. -        if (CR)
  2115. -            tputs(CR, 1, plodput);
  2116. -        else
  2117. -            *plodstr++ = '\r';
  2118. -        if (_relhmove(0, ncol, row) >= 0
  2119. -         && (newcost = plodstr - ret) < cost) {
  2120. -            cost = newcost;
  2121. -            movstr = ret;
  2122. -        }
  2123. -        plodstr = saveplod;
  2124. -    }
  2125. -    if (_relhmove(ocol, ncol, row) < 0) {
  2126. -        if (cost == 999)
  2127. -            return -1;
  2128. -        goto copy;
  2129. -    }
  2130. -    if (plodstr - saveplod > cost) {
  2131. -copy:        plodstr = saveplod;
  2132. -        while (--cost >= 0)
  2133. -            *plodstr++ = *movstr++;
  2134. -    }
  2135. -    return 0;
  2136. -}
  2137. -
  2138. -_relhmove(ocol, ncol, row)
  2139. -{
  2140. -    int tab;
  2141. -
  2142. -    if (ocol < ncol && PT && GT) {    /* tab (nondestructive) */
  2143. -        while ((tab = (ocol + 8) & ~07) <= ncol) {
  2144. -            if (TA)
  2145. -                tputs(TA, 1, plodput);
  2146. -            else
  2147. -                *plodstr++ = '\t';
  2148. -            ocol = tab;
  2149. -        }
  2150. -        if (tab < COLS && tab - ncol < ncol - ocol) {
  2151. -            if (TA)
  2152. -                tputs(TA, 1, plodput);
  2153. -            else
  2154. -                *plodstr++ = '\t';
  2155. -            ocol = tab;
  2156. -        }
  2157. -    } else if (BT && GT && ocol > ncol) {    /* backwards tab */
  2158. -        while ((tab = (ocol - 1) &~ 07) >= ncol) {
  2159. -            if (BS && tab == ocol - 1) {
  2160. -                if (BC)
  2161. -                    tputs(BC, 1, plodput);
  2162. -                else
  2163. -                    *plodstr++ = '\b';
  2164. -            } else
  2165. -                tputs(BT, 1, plodput);
  2166. -            ocol = tab;
  2167. -        }
  2168. -        if (ncol - tab + 1 < ocol - ncol) {
  2169. -            tputs(BT, 1, plodput);
  2170. -            ocol = tab;
  2171. -        }
  2172. -    }
  2173. -    if (ocol > ncol) {            /* cursor left */
  2174. -        if (! BS)
  2175. -            return -1;
  2176. -        while (ocol > ncol) {
  2177. -            if (BC != NULL)
  2178. -                tputs(BC, 1, plodput);
  2179. -            else
  2180. -                *plodstr++ = '\b';
  2181. -            ocol--;
  2182. -        }
  2183. -    }
  2184. -    if (ocol < ncol) {            /* cursor right */
  2185. -        register struct line *lp = &_actual[row];
  2186. -        /*
  2187. -         * This code doesn't move over underlined characters properly,
  2188. -         * but in practice this doesn't seem to matter.
  2189. -         */
  2190. -        while (ocol < ncol) {
  2191. -            if (ocol < lp->len)
  2192. -                *plodstr++ = lp->l[ocol];
  2193. -            else
  2194. -                *plodstr++ = ' ';
  2195. -            ocol++;
  2196. -        }
  2197. -    }
  2198. -    return 0;
  2199. -}
  2200. -
  2201. -_aputc(c)
  2202. -{
  2203. -    if (_uline != (c & ULINE))    /* Inline for speed */
  2204. -        _setul(c & ULINE);
  2205. -    if (++_scol >= COLS) {
  2206. -        if (_srow == ROWS - 1) {
  2207. -            /* Don't ever paint last char of last line */
  2208. -            _scol--;
  2209. -            return;
  2210. -        }
  2211. -        _curjunked++;        /* Don't assume AM is right */
  2212. -    }
  2213. -    vputc(c & ~ULINE);
  2214. -}
  2215. -
  2216. -
  2217. -_setul(on)
  2218. -{
  2219. -    if (on) {
  2220. -        if (_uline == 0 && US != NULL) {
  2221. -            tputs(US, 1, vputc);
  2222. -            _uline = ULINE;
  2223. -        }
  2224. -    }
  2225. -    else {
  2226. -        if (_uline != 0 && UE != NULL) {
  2227. -            tputs(UE, 1, vputc);
  2228. -            _uline = 0;
  2229. -        }
  2230. -    }
  2231. -}
  2232. -
  2233. -/*
  2234. - * Initialize termcap strings for later use.
  2235. - */
  2236. -
  2237. -/*
  2238. - * Hacks to help with some Tek terminals
  2239. - * rad@tek
  2240. - */
  2241. -int tputs_len;
  2242. -countit(c) { tputs_len++; }
  2243. -
  2244. -initterm()
  2245. -{
  2246. -    static char tcbuf[1024];    /* termcap buffer */
  2247. -    register char  *cp;
  2248. -#ifdef USG
  2249. -    struct termio tio;
  2250. -#else /* !USG */
  2251. -    struct sgttyb ttyb;
  2252. -#endif /* !USG */
  2253. -
  2254. -    if ((cp = getenv("TERM")) == NULL)
  2255. -        xerror("TERM not set in environment");
  2256. -
  2257. -    switch (tgetent(tcbuf, cp)) {
  2258. -        case 0:
  2259. -            xerror("Terminal not found in TERMCAP");
  2260. -        case -1:
  2261. -            xerror("Can't open /etc/termcap");
  2262. -        case 1:
  2263. -            break;
  2264. -    }
  2265. -#ifdef TIOCGWINSZ
  2266. -    {
  2267. -        struct winsize ws;
  2268. -        int winch();
  2269. -
  2270. -        COLS = ROWS = -1;
  2271. -        if(ioctl(1, TIOCGWINSZ, &ws) == 0) {
  2272. -            ROWS = ws.ws_row;
  2273. -            COLS = ws.ws_col;
  2274. -        }
  2275. -        if(ROWS <= 0)
  2276. -            ROWS = tgetnum("li");
  2277. -        if(COLS <= 0)
  2278. -            COLS = tgetnum("co");
  2279. -        if ((ROWS <= 0) || (COLS <= 0))
  2280. -            xerror("Can't get screen size");
  2281. -
  2282. -        signal(SIGWINCH, winch); /* allow for changing window size */
  2283. -    }
  2284. -#else /* !TIOCGWINSZ */
  2285. -    if ((ROWS = tgetnum("li")) == -1
  2286. -        || (COLS = tgetnum("co")) == -1)
  2287. -        xerror("Can't get screen size");
  2288. -#endif /* !TIOCGWINSZ */
  2289. -    _zap();
  2290. -
  2291. -    if (CL == NULL)
  2292. -        xerror ("No clear screen defined");
  2293. -
  2294. -    if (HO == NULL && CM == NULL)
  2295. -        xerror("No home or cursor addressing");
  2296. -    if (HO)
  2297. -        HOlen = strlen(HO);
  2298. -    else
  2299. -        HOlen = 999;
  2300. -
  2301. -    PC = xPC ? xPC[0] : 0;
  2302. -    BC = xBC;
  2303. -    UP = xUP;
  2304. -    /*
  2305. -     *  _vmove() may be called with a full-screen traverse,
  2306. -     * meaning it will put the UP (along with any padding) into
  2307. -     * the buffer as many as MAXPLEN times.  This means that
  2308. -     * if the UP string would be more than 10 chars long (defined
  2309. -     * in _amove() ), the buffer might be overflowed (assuming
  2310. -     * CH is also large).
  2311. -     * This actually occurs with the Tek4023 termcap, where :up=1000UP:
  2312. -     * is used to fake vi into using :cm instead, due to the fact
  2313. -     * that a 4023 can't do upline relative motion at all.
  2314. -     * -rdoty@tek
  2315. -     */
  2316. -    if (UP) {
  2317. -        tputs_len = 0;
  2318. -        tputs(UP, 1, countit);
  2319. -        if (tputs_len > 10 )
  2320. -            UP = 0;
  2321. -    }
  2322. -
  2323. -    if (tgetnum("ug") > 0)
  2324. -        US = UE = NULL;
  2325. -
  2326. -    if (XT)                /* Destructive tab code not included */
  2327. -        PT = 0;            /* to keep things simple */
  2328. -
  2329. -#ifdef USG
  2330. -    if (ioctl(0, TCGETA, &tio) == 0)
  2331. -        GT = tio.c_oflag&TAB3;
  2332. -#else /* !USG */
  2333. -    if (ioctl(0, TIOCGETP, &ttyb) == 0)
  2334. -        GT = ttyb.sg_flags&XTABS;
  2335. -#endif /* !USG */
  2336. -
  2337. -    {
  2338. -        char *thelines;
  2339. -        int i;
  2340. -        char *malloc();
  2341. -
  2342. -        thelines = malloc(2 * ROWS * COLS);
  2343. -        _virt = (struct line *)malloc(2 * ROWS * sizeof (struct line));
  2344. -        _actual = _virt + ROWS;
  2345. -        for (i = 0; i < ROWS; i++) {
  2346. -            _virt[i].len = 0;
  2347. -            _virt[i].flags = 0;
  2348. -            _actual[i].len = 0;
  2349. -            _actual[i].flags = 0;
  2350. -            _virt[i].l = thelines;
  2351. -            thelines += COLS;
  2352. -            _actual[i].l = thelines;
  2353. -            thelines += COLS;
  2354. -        }
  2355. -    }
  2356. -
  2357. -    /* Select article scrolling algorithm.  We prefer scrolling region
  2358. -       over insert/delete line because it's faster on the HP */
  2359. -    hasscroll = 0;
  2360. -    if (!NS) {
  2361. -        hasscroll = 1;
  2362. -        if (SR)
  2363. -            hasscroll = 3;
  2364. -        if (CS)
  2365. -            hasscroll++;
  2366. -    }
  2367. -    if (AL && DL && hasscroll != 4)
  2368. -        hasscroll = 5;
  2369. -}
  2370. -
  2371. -rawterm()
  2372. -{
  2373. -    if (TI != NULL)
  2374. -        tputs(TI, 0, vputc);
  2375. -}
  2376. -
  2377. -cookedterm()
  2378. -{
  2379. -    if (TE != NULL) {
  2380. -        tputs(TE, 0, vputc);
  2381. -        vflush();
  2382. -    }
  2383. -}
  2384. -
  2385. -/* get strings from termcap */
  2386. -_zap()
  2387. -{
  2388. -    static char tstrbuf[1024];
  2389. -    static char *tp;
  2390. -    register char  *namp, **sp, *bp;
  2391. -
  2392. -    tp = tstrbuf;
  2393. -    sp = _tstr;
  2394. -    for (namp = sname; *namp; namp += 2) {
  2395. -        *sp++ = tgetstr(namp, &tp);
  2396. -    }
  2397. -    bp = _tflg;
  2398. -    for (namp = bname; *namp; namp += 2) {
  2399. -        *bp++ = tgetflag(namp, &tp);
  2400. -    }
  2401. -}
  2402. -#ifdef TIOCGWINSZ
  2403. -/*
  2404. - * window changed size -- update ROWS and COLS
  2405. - * and then redraw screen
  2406. - */
  2407. -winch()
  2408. -{
  2409. -    struct winsize ws;
  2410. -    int cols, rows;
  2411. -
  2412. -    cols = rows = -1;
  2413. -    if(ioctl(1, TIOCGWINSZ, &ws) == 0) {
  2414. -        rows = ws.ws_row;
  2415. -        cols = ws.ws_col;
  2416. -    }
  2417. -    if (rows == ROWS && cols == COLS) { /* just redraw it if no change */
  2418. -        _junked = 1;    /* redraw */
  2419. -        updscr();
  2420. -        return;
  2421. -    }
  2422. -
  2423. -    if(rows > 0)
  2424. -        ROWS = rows;
  2425. -    if(cols > 0)
  2426. -        COLS = cols;
  2427. -
  2428. -    if (ROWS > MAXPLEN)
  2429. -        ROWS = MAXPLEN;
  2430. -    if (COLS > MAXLLEN) {
  2431. -        COLS = MAXLLEN;
  2432. -        AM = XN = 1;
  2433. -    }
  2434. -
  2435. -    winch_upd();
  2436. -}
  2437. -#endif TIOCGWINSZ
  2438. *-*-END-of-src/virtterm.c-*-*
  2439. echo x - src/decode.c 1>&2
  2440. sed 's/.//' >src/decode.c <<'*-*-END-of-src/decode.c-*-*'
  2441. -#include <stdio.h>
  2442. -
  2443. -#ifdef SCCSID
  2444. -static char    *SccsId = "@(#)decode.c    1.3    5/15/85";
  2445. -#endif /* SCCSID */
  2446. -
  2447. -/*
  2448. - * This program is the inverse of encode
  2449. - *
  2450. - * It collects runs of 12 characters, combines pairs of those
  2451. - * to form 6 13 bit numbers, extracts the top bit of each of
  2452. - * those to make a 13th 6 bit character, and splits each of
  2453. - * the remaining 6 12 bit numbers to form 12 6 bit ones.
  2454. - *
  2455. - * The strings of 6 bit numbers are collected into groups of
  2456. - * 4 and converted into 3 8 bit characters.
  2457. - *
  2458. - * Now all that would be trivial, if we didn't need to worry
  2459. - * about ending all this correctly.  About 1/2 of the following
  2460. - * program wouldn't be here if the ending didn't matter....
  2461. - */
  2462. -
  2463. -/*
  2464. - * the following pair of characters can never occur as a pair
  2465. - * in legal input (since (90 * 91 + 90) > 2^13) - they are
  2466. - * noticed at the beginning of a 12 char block, and serve to
  2467. - * indicate that this block is the terminator.  The character
  2468. - * immediately following is the (expanded) terminator length.
  2469. - */
  2470. -#define    ENDMARK1    ((90*91 + 90) / 91)
  2471. -#define    ENDMARK2    ((90*91 + 90) % 91)
  2472. -
  2473. -main()
  2474. -{
  2475. -    register c;
  2476. -    register char *p;
  2477. -    register i;
  2478. -    register first = 1;
  2479. -    register cnt = 0;
  2480. -    int errcnt = 0;
  2481. -    char b12[12];
  2482. -    char c12[12];
  2483. -
  2484. -    p = b12;
  2485. -    i = 12;
  2486. -
  2487. -    while ((c = getchar()) != EOF) {
  2488. -        if (c < ' ' || c >= (' ' + 91)) {
  2489. -            if (errcnt++ == 0)
  2490. -                fprintf(stderr, "decode: Bad data\n");
  2491. -            continue;
  2492. -        }
  2493. -        if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
  2494. -            cnt = c - ' ';
  2495. -            i = 12;
  2496. -            p -= 2;
  2497. -            continue;
  2498. -        }
  2499. -        *p++ = c - ' ';
  2500. -        if (--i == 0) {
  2501. -            if (p == &b12[12]) {
  2502. -                if (!first)
  2503. -                    pack12(c12, 12, 0);
  2504. -                else
  2505. -                    first = 0;
  2506. -                p = c12;
  2507. -            } else {
  2508. -                pack12(b12, 12, 0);
  2509. -                p = b12;
  2510. -            }
  2511. -            i = 12;
  2512. -        }
  2513. -    }
  2514. -
  2515. -    if (p >= &b12[0] && p < &b12[12]) {
  2516. -        if (!first)
  2517. -            pack12(c12, 12, i == 12 ? cnt : 0);
  2518. -    } else
  2519. -        pack12(b12, 12, i == 12 ? cnt : 0);
  2520. -
  2521. -    if (i != 12) {
  2522. -        if (p >= &b12[0] && p < &b12[12])
  2523. -            pack12(b12, 12-i, cnt);
  2524. -        else
  2525. -            pack12(c12, 12-i, cnt);
  2526. -    }
  2527. -
  2528. -    exit(0);
  2529. -}
  2530. -
  2531. -static char b4[4];
  2532. -static int cnt = 0;
  2533. -
  2534. -pack12(p, n, last)
  2535. -    register char *p;
  2536. -    register n;
  2537. -    int last;
  2538. -{
  2539. -    register i;
  2540. -    register char *q;
  2541. -    char b13[13];
  2542. -
  2543. -    {
  2544. -        register c;
  2545. -        register c13;
  2546. -
  2547. -        q = b13;
  2548. -        c13 = 0;
  2549. -
  2550. -        for (i = 0; i < n; i += 2) {
  2551. -            c = *p++ * 91;
  2552. -            c += *p++;
  2553. -            c13 <<= 1;
  2554. -            if (c & (1 << 12))
  2555. -                c13 |= 1;
  2556. -            *q++ = (c >> 6) & 0x3f;
  2557. -            *q++ = c & 0x3f;
  2558. -        }
  2559. -        *q++ = c13;
  2560. -        if (last)
  2561. -            q = &b13[last];
  2562. -    }
  2563. -
  2564. -    p = b13;
  2565. -    n = q - p;
  2566. -    i = cnt;
  2567. -    q = &b4[cnt];
  2568. -
  2569. -    while (--n > 0) {
  2570. -        *q++ = *p++;
  2571. -        if (++i == 4) {
  2572. -            char b3[3];
  2573. -            register char *b = b4;
  2574. -
  2575. -            /* inline expansion of pack6bit, to save calls ... */
  2576. -
  2577. -            q = b3;
  2578. -            *q++ = (b[0] << 2) | ((b[1] >> 4) & 0x3);
  2579. -            *q++ = (b[1] << 4) | ((b[2] >> 2) & 0xf);
  2580. -            *q = (b[2] << 6) | (b[3] & 0x3f);
  2581. -
  2582. -            q = b3;
  2583. -            while (--i > 0)
  2584. -                putchar(*q++);
  2585. -
  2586. -            q = b4;
  2587. -        }
  2588. -    }
  2589. -
  2590. -    *q++ = *p++;    /* the last octet */
  2591. -    ++i;
  2592. -
  2593. -    if (last || i == 4) {
  2594. -        pack6bit(b4, i, last);
  2595. -        i = 0;
  2596. -    }
  2597. -
  2598. -    cnt = i;
  2599. -}
  2600. -
  2601. -pack6bit(p, n, last)
  2602. -    register char *p;
  2603. -    register int n;
  2604. -    int last;
  2605. -{
  2606. -    register char *q;
  2607. -    register i = 3;
  2608. -    char b3[3];
  2609. -
  2610. -    if (last) {
  2611. -        i = p[n-1];
  2612. -        if (i >= 3) {
  2613. -            fprintf(stderr, "Badly encoded file\n");
  2614. -            i = 3;        /* do the best we can */
  2615. -        }
  2616. -    }
  2617. -
  2618. -    q = b3;
  2619. -    *q++ = (p[0] << 2) | ((p[1] >> 4) & 0x3);
  2620. -    *q++ = (p[1] << 4) | ((p[2] >> 2) & 0xf);
  2621. -    *q = (p[2] << 6) | (p[3] & 0x3f);
  2622. -
  2623. -    q = b3;
  2624. -
  2625. -    while (--i >= 0)
  2626. -        putchar(*q++);
  2627. -}
  2628. *-*-END-of-src/decode.c-*-*
  2629. exit
  2630.  
  2631.